# -*- coding: utf-8 -*-
"""
股票预测应用主界面 - Streamlit Web应用
"""
import streamlit as st
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
from datetime import datetime, timedelta
import logging
import time

# 导入自定义模块
from data_fetcher import get_data_fetcher
from stock_screener import StockScreener
from technical_analysis import TechnicalAnalyzer
from prediction_model import StockPredictor
from config import SCREENING_CRITERIA, DISPLAY_CONFIG

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 页面配置
st.set_page_config(
    page_title="股票预测分析系统",
    page_icon="📈",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 缓存数据获取函数
@st.cache_data(ttl=3600)  # 缓存1小时
def get_stock_list():
    """获取股票列表"""
    fetcher = get_data_fetcher()
    return fetcher.get_stock_list()

@st.cache_data(ttl=1800)  # 缓存30分钟
def get_historical_data(stock_code, start_date, end_date):
    """获取历史数据"""
    fetcher = get_data_fetcher()
    return fetcher.get_stock_historical_data(stock_code, start_date, end_date)

@st.cache_data(ttl=1800)  # 缓存30分钟
def screen_stocks():
    """筛选股票"""
    screener = StockScreener()
    return screener.screen_stocks()

class StockAnalysisApp:
    """股票分析应用"""
    
    def __init__(self):
        self.data_fetcher = get_data_fetcher()
        self.screener = StockScreener()
        self.analyzer = TechnicalAnalyzer()
        self.predictor = StockPredictor()
        
    def run(self):
        """运行应用"""
        st.title("🎯 A股中长期投资分析系统")
        st.markdown("---")
        
        # 侧边栏
        self._render_sidebar()
        
        # 主要内容区域
        tab1, tab2, tab3, tab4 = st.tabs(["📊 股票筛选", "📈 技术分析", "🔮 趋势预测", "📋 投资建议"])
        
        with tab1:
            self._render_stock_screening()
        
        with tab2:
            self._render_technical_analysis()
        
        with tab3:
            self._render_prediction()
        
        with tab4:
            self._render_investment_advice()
    
    def _render_sidebar(self):
        """渲染侧边栏"""
        st.sidebar.title("🔧 系统设置")
        
        # 筛选条件设置
        st.sidebar.subheader("筛选条件")
        
        market_cap_min = st.sidebar.slider(
            "最小市值 (亿元)", 
            min_value=10, 
            max_value=200, 
            value=SCREENING_CRITERIA['market_cap_min']
        )
        
        price_range = st.sidebar.slider(
            "股价区间 (元)", 
            min_value=1.0, 
            max_value=50.0, 
            value=(SCREENING_CRITERIA['price_min'], SCREENING_CRITERIA['price_max'])
        )
        
        require_dividend = st.sidebar.checkbox(
            "必须有分红记录", 
            value=SCREENING_CRITERIA['dividend_required']
        )
        
        top_stocks = st.sidebar.slider(
            "选出股票数量", 
            min_value=3, 
            max_value=20, 
            value=SCREENING_CRITERIA['top_stocks']
        )
        
        # 更新配置
        if st.sidebar.button("更新筛选条件"):
            SCREENING_CRITERIA.update({
                'market_cap_min': market_cap_min,
                'price_min': price_range[0],
                'price_max': price_range[1],
                'dividend_required': require_dividend,
                'top_stocks': top_stocks
            })
            st.cache_data.clear()  # 清除缓存
            st.success("筛选条件已更新！")
        
        # 系统状态
        st.sidebar.subheader("系统状态")
        
        try:
            # 测试数据连接
            test_data = get_stock_list()
            if not test_data.empty:
                st.sidebar.success("🟢 数据源连接正常")
                st.sidebar.info(f"📊 股票数据: {len(test_data)} 只")
            else:
                st.sidebar.error("🔴 数据源连接异常")
        except Exception as e:
            st.sidebar.error(f"🔴 数据源错误: {str(e)}")
        
        # 更新时间
        st.sidebar.info(f"⏰ 最后更新: {datetime.now().strftime('%H:%M:%S')}")
        
        if st.sidebar.button("🔄 刷新数据"):
            st.cache_data.clear()
            st.rerun()
    
    def _render_stock_screening(self):
        """渲染股票筛选页面"""
        st.header("📊 智能股票筛选")
        
        col1, col2 = st.columns([2, 1])
        
        with col2:
            st.subheader("筛选标准")
            st.write(f"💰 市值: ≥{SCREENING_CRITERIA['market_cap_min']}亿元")
            st.write(f"💵 股价: {SCREENING_CRITERIA['price_min']}-{SCREENING_CRITERIA['price_max']}元")
            st.write("📈 市盈率: 正值（盈利股票）")
            st.write(f"🎁 分红: {'必须有' if SCREENING_CRITERIA['dividend_required'] else '优先考虑'}")
        
        with col1:
            if st.button("🔍 开始筛选股票", type="primary"):
                with st.spinner("正在筛选股票，请稍候..."):
                    try:
                        # 执行筛选
                        filtered_stocks = screen_stocks()
                        
                        if not filtered_stocks.empty:
                            st.success(f"✅ 筛选完成！找到 {len(filtered_stocks)} 只符合条件的股票")
                            
                            # 存储到session state
                            st.session_state['filtered_stocks'] = filtered_stocks
                            
                            # 显示结果
                            self._display_filtered_stocks(filtered_stocks)
                        else:
                            st.warning("⚠️ 未找到符合条件的股票，请调整筛选条件")
                    
                    except Exception as e:
                        st.error(f"❌ 筛选失败: {str(e)}")
                        logger.error(f"股票筛选失败: {e}")
        
        # 显示已筛选的股票
        if 'filtered_stocks' in st.session_state:
            st.subheader("📋 筛选结果")
            self._display_filtered_stocks(st.session_state['filtered_stocks'])
    
    def _display_filtered_stocks(self, stocks_df):
        """显示筛选的股票"""
        if stocks_df.empty:
            return
        
        # 数据清洗和格式化
        display_columns = ['code', 'name', 'total_score', 'technical_score', 
                          'fundamental_score', 'momentum_score', 'dividend_score']
        
        # 检查列是否存在
        available_columns = [col for col in display_columns if col in stocks_df.columns]
        
        if len(available_columns) < 3:
            st.warning("数据列不完整，显示可用数据")
            available_columns = stocks_df.columns.tolist()[:6]
        
        display_df = stocks_df[available_columns].head(20)
        
        # 格式化数值列
        numeric_columns = display_df.select_dtypes(include=[np.number]).columns
        for col in numeric_columns:
            display_df[col] = display_df[col].round(2)
        
        # 显示表格
        st.dataframe(
            display_df,
            use_container_width=True,
            height=400
        )
        
        # 评分分布图
        if 'total_score' in display_df.columns:
            fig = px.bar(
                display_df.head(10), 
                x='name', 
                y='total_score',
                title="Top 10 股票评分分布",
                labels={'total_score': '总评分', 'name': '股票名称'}
            )
            fig.update_layout(xaxis_tickangle=-45)
            st.plotly_chart(fig, use_container_width=True)
        
        # 选择股票进行详细分析
        st.subheader("🎯 选择股票进行详细分析")
        
        col1, col2 = st.columns(2)
        with col1:
            selected_stocks = st.multiselect(
                "选择最多3只股票进行深度分析",
                options=stocks_df['code'].tolist()[:10],
                format_func=lambda x: f"{x} - {stocks_df[stocks_df['code']==x]['name'].iloc[0] if not stocks_df[stocks_df['code']==x].empty else x}",
                max_selections=3
            )
        
        with col2:
            if selected_stocks and st.button("📊 开始详细分析"):
                st.session_state['selected_stocks'] = selected_stocks
                st.success(f"已选择 {len(selected_stocks)} 只股票进行分析")
    
    def _render_technical_analysis(self):
        """渲染技术分析页面"""
        st.header("📈 技术分析")
        
        if 'selected_stocks' not in st.session_state:
            st.info("⏳ 请先在股票筛选页面选择要分析的股票")
            return
        
        selected_stocks = st.session_state['selected_stocks']
        
        # 股票选择器
        selected_stock = st.selectbox(
            "选择要分析的股票",
            options=selected_stocks,
            format_func=lambda x: f"{x} - {self._get_stock_name(x)}"
        )
        
        if selected_stock:
            self._perform_technical_analysis(selected_stock)
    
    def _perform_technical_analysis(self, stock_code):
        """执行技术分析"""
        with st.spinner(f"正在分析股票 {stock_code}..."):
            try:
                # 获取历史数据
                end_date = datetime.now().strftime("%Y%m%d")
                start_date = (datetime.now() - timedelta(days=365)).strftime("%Y%m%d")
                
                hist_data = get_historical_data(stock_code, start_date, end_date)
                
                if hist_data.empty:
                    st.error("❌ 无法获取股票数据")
                    return
                
                # 技术分析
                analyzed_data = self.analyzer.calculate_all_indicators(hist_data)
                current_signals = self.analyzer.get_current_signals(analyzed_data)
                
                # 显示当前状态
                self._display_current_status(stock_code, analyzed_data, current_signals)
                
                # 显示技术图表
                self._display_technical_charts(stock_code, analyzed_data)
                
                # 显示技术指标表
                self._display_technical_indicators(analyzed_data)
                
            except Exception as e:
                st.error(f"❌ 技术分析失败: {str(e)}")
                logger.error(f"技术分析失败 {stock_code}: {e}")
    
    def _display_current_status(self, stock_code, data, signals):
        """显示当前状态"""
        st.subheader(f"📊 {stock_code} 当前状态")
        
        col1, col2, col3, col4 = st.columns(4)
        
        current_price = data['close'].iloc[-1]
        price_change = (current_price - data['close'].iloc[-2]) / data['close'].iloc[-2] * 100
        
        with col1:
            st.metric(
                label="当前价格",
                value=f"¥{current_price:.2f}",
                delta=f"{price_change:+.2f}%"
            )
        
        with col2:
            st.metric(
                label="趋势状态",
                value=signals.get('trend_status', '未知')
            )
        
        with col3:
            st.metric(
                label="信号强度",
                value=f"{signals.get('signal_strength', 0)}/6"
            )
        
        with col4:
            risk_level = signals.get('risk_level', '未知')
            st.metric(
                label="风险等级",  
                value=risk_level
            )
        
        # 交易信号
        if signals.get('buy_signal'):
            st.success("🔥 买入信号！")
        elif signals.get('sell_signal'):
            st.error("⚠️ 卖出信号！")
        else:
            st.info("➡️ 持有观望")
        
        # 投资建议
        recommendation = signals.get('recommendation', '持有观望')
        st.info(f"💡 投资建议: {recommendation}")
    
    def _display_technical_charts(self, stock_code, data):
        """显示技术图表"""
        st.subheader("📈 技术分析图表")
        
        # 创建子图
        fig = make_subplots(
            rows=3, cols=1,
            shared_xaxis=True,
            vertical_spacing=0.05,
            subplot_titles=('K线图与技术指标', 'MACD', '成交量'),
            row_heights=[0.6, 0.2, 0.2]
        )
        
        # K线图
        fig.add_trace(
            go.Candlestick(
                x=data.index,
                open=data['open'],
                high=data['high'],
                low=data['low'],
                close=data['close'],
                name='K线'
            ),
            row=1, col=1
        )
        
        # 添加均线
        if 'P1' in data.columns:
            fig.add_trace(
                go.Scatter(x=data.index, y=data['P1'], name='EMA5', line=dict(color='orange')),
                row=1, col=1
            )
        
        if 'P2' in data.columns:
            fig.add_trace(
                go.Scatter(x=data.index, y=data['P2'], name='EMA8', line=dict(color='blue')),
                row=1, col=1
            )
        
        if 'P3' in data.columns:
            fig.add_trace(
                go.Scatter(x=data.index, y=data['P3'], name='EMA55', line=dict(color='purple')),
                row=1, col=1
            )
        
        # 买卖点标记
        if 'buy_signal' in data.columns:
            buy_points = data[data['buy_signal']]
            if not buy_points.empty:
                fig.add_trace(
                    go.Scatter(
                        x=buy_points.index,
                        y=buy_points['low'],
                        mode='markers',
                        marker=dict(symbol='triangle-up', size=15, color='red'),
                        name='买入信号'
                    ),
                    row=1, col=1
                )
        
        if 'sell_signal' in data.columns:
            sell_points = data[data['sell_signal']]
            if not sell_points.empty:
                fig.add_trace(
                    go.Scatter(
                        x=sell_points.index,
                        y=sell_points['high'],
                        mode='markers',
                        marker=dict(symbol='triangle-down', size=15, color='green'),
                        name='卖出信号'
                    ),
                    row=1, col=1
                )
        
        # MACD
        if 'MACD' in data.columns:
            fig.add_trace(
                go.Scatter(x=data.index, y=data['MACD'], name='MACD', line=dict(color='blue')),
                row=2, col=1
            )
            
            if 'MACD_signal' in data.columns:
                fig.add_trace(
                    go.Scatter(x=data.index, y=data['MACD_signal'], name='Signal', line=dict(color='red')),
                    row=2, col=1
                )
            
            if 'MACD_hist' in data.columns:
                colors = ['red' if val >= 0 else 'green' for val in data['MACD_hist']]
                fig.add_trace(
                    go.Bar(x=data.index, y=data['MACD_hist'], name='Histogram', marker_color=colors),
                    row=2, col=1
                )
        
        # 成交量
        fig.add_trace(
            go.Bar(x=data.index, y=data['volume'], name='成交量', marker_color='lightblue'),
            row=3, col=1
        )
        
        # 更新布局
        fig.update_layout(
            title=f"{stock_code} 技术分析图表",
            height=800,
            showlegend=True,
            xaxis_rangeslider_visible=False
        )
        
        st.plotly_chart(fig, use_container_width=True)
    
    def _display_technical_indicators(self, data):
        """显示技术指标表"""
        st.subheader("📋 技术指标一览")
        
        if data.empty:
            return
        
        # 最新的技术指标值
        latest = data.iloc[-1]
        
        indicators = {
            '指标': ['RSI', 'MACD', 'KDJ-K', 'KDJ-D', 'KDJ-J', 'ATR', '成交量比率'],
            '数值': [
                f"{latest.get('RSI', 0):.2f}",
                f"{latest.get('MACD', 0):.4f}",
                f"{latest.get('K', 0):.2f}",
                f"{latest.get('D', 0):.2f}",
                f"{latest.get('J', 0):.2f}",
                f"{latest.get('ATR', 0):.2f}",
                f"{latest.get('volume_ratio', 0):.2f}"
            ],
            '状态': [
                '超买' if latest.get('RSI', 50) > 70 else ('超卖' if latest.get('RSI', 50) < 30 else '正常'),
                '多头' if latest.get('MACD', 0) > 0 else '空头',
                '超买' if latest.get('K', 50) > 80 else ('超卖' if latest.get('K', 50) < 20 else '正常'),
                '超买' if latest.get('D', 50) > 80 else ('超卖' if latest.get('D', 50) < 20 else '正常'),
                '超买' if latest.get('J', 50) > 100 else ('超卖' if latest.get('J', 50) < 0 else '正常'),
                '高波动' if latest.get('ATR', 0) > latest.get('close', 0) * 0.05 else '低波动',
                '放量' if latest.get('volume_ratio', 1) > 1.5 else '缩量'
            ]
        }
        
        indicators_df = pd.DataFrame(indicators)
        st.dataframe(indicators_df, use_container_width=True)
    
    def _render_prediction(self):
        """渲染预测页面"""
        st.header("🔮 股票趋势预测")
        
        if 'selected_stocks' not in st.session_state:
            st.info("⏳ 请先在股票筛选页面选择要预测的股票")
            return
        
        selected_stocks = st.session_state['selected_stocks']
        
        # 股票选择器
        selected_stock = st.selectbox(
            "选择要预测的股票",
            options=selected_stocks,
            format_func=lambda x: f"{x} - {self._get_stock_name(x)}",
            key="prediction_stock_selector"
        )
        
        if selected_stock:
            col1, col2 = st.columns([3, 1])
            
            with col2:
                forecast_days = st.slider("预测天数", min_value=7, max_value=60, value=30)
                
                if st.button("🔮 开始预测", type="primary"):
                    self._perform_prediction(selected_stock, forecast_days)
            
            with col1:
                if f'prediction_{selected_stock}' in st.session_state:
                    self._display_prediction_results(selected_stock)
    
    def _perform_prediction(self, stock_code, forecast_days):
        """执行预测"""
        with st.spinner(f"正在预测股票 {stock_code} 未来 {forecast_days} 天走势..."):
            try:
                # 获取更长的历史数据用于预测
                end_date = datetime.now().strftime("%Y%m%d")
                start_date = (datetime.now() - timedelta(days=730)).strftime("%Y%m%d")  # 2年数据
                
                hist_data = get_historical_data(stock_code, start_date, end_date)
                
                if hist_data.empty:
                    st.error("❌ 无法获取足够的历史数据")
                    return
                
                # 更新预测配置
                original_forecast = self.predictor.config['forecast_days']
                self.predictor.config['forecast_days'] = forecast_days
                
                # 执行预测
                prediction_result = self.predictor.predict_stock_trend(hist_data, stock_code)
                
                # 恢复原配置
                self.predictor.config['forecast_days'] = original_forecast
                
                # 存储预测结果
                st.session_state[f'prediction_{stock_code}'] = {
                    'result': prediction_result,
                    'historical_data': hist_data,
                    'forecast_days': forecast_days
                }
                
                st.success(f"✅ 预测完成！")
                
            except Exception as e:
                st.error(f"❌ 预测失败: {str(e)}")
                logger.error(f"预测失败 {stock_code}: {e}")
    
    def _display_prediction_results(self, stock_code):
        """显示预测结果"""
        prediction_data = st.session_state[f'prediction_{stock_code}']
        result = prediction_data['result']
        hist_data = prediction_data['historical_data']
        
        st.subheader(f"📊 {stock_code} 预测结果")
        
        # 预测摘要
        col1, col2, col3, col4 = st.columns(4)
        
        current_price = result.get('current_price', 0)
        price_change = result.get('price_change_pct', 0)
        confidence = result.get('confidence', 0)
        trend = result.get('trend', '未知')
        
        with col1:
            st.metric(
                label="当前价格",
                value=f"¥{current_price:.2f}"
            )
        
        with col2:
            st.metric(
                label="预测趋势",
                value=trend,
                delta=f"{price_change:+.2f}%"
            )
        
        with col3:
            st.metric(
                label="置信度",
                value=f"{confidence:.1%}"
            )
        
        with col4:
            risk_level = result.get('risk_assessment', {}).get('risk_level', '未知')
            st.metric(
                label="风险等级",
                value=risk_level
            )
        
        # 预测图表
        self._display_prediction_chart(stock_code, hist_data, result)
        
        # 风险评估
        self._display_risk_assessment(result.get('risk_assessment', {}))
        
        # 各模型预测对比
        self._display_model_comparison(result.get('individual_predictions', {}))
    
    def _display_prediction_chart(self, stock_code, hist_data, prediction):
        """显示预测图表"""
        st.subheader("📈 价格预测图表")
        
        # 准备数据
        predictions = prediction.get('predictions', [])
        dates = prediction.get('dates', [])
        
        if not predictions or not dates:
            st.warning("预测数据不完整")
            return
        
        # 历史数据（最近60天）
        recent_hist = hist_data.tail(60)
        
        # 创建图表
        fig = go.Figure()
        
        # 历史价格
        fig.add_trace(
            go.Scatter(
                x=recent_hist.index,
                y=recent_hist['close'],
                mode='lines',
                name='历史价格',
                line=dict(color='blue')
            )
        )
        
        # 预测价格
        pred_dates = pd.to_datetime(dates)
        fig.add_trace(
            go.Scatter(
                x=pred_dates,
                y=predictions,
                mode='lines+markers',
                name='预测价格',
                line=dict(color='red', dash='dash'),
                marker=dict(size=6)
            )
        )
        
        # 置信区间（如果有）
        if 'upper_bound' in prediction and 'lower_bound' in prediction:
            upper_bound = prediction['upper_bound']
            lower_bound = prediction['lower_bound']
            
            fig.add_trace(
                go.Scatter(
                    x=pred_dates,
                    y=upper_bound,
                    fill=None,
                    mode='lines',
                    line_color='rgba(0,0,0,0)',
                    name='上界'
                )
            )
            
            fig.add_trace(
                go.Scatter(
                    x=pred_dates,
                    y=lower_bound,
                    fill='tonexty',
                    mode='lines',
                    line_color='rgba(0,0,0,0)',
                    name='置信区间',
                    fillcolor='rgba(255,0,0,0.2)'
                )
            )
        
        # 更新布局
        fig.update_layout(
            title=f"{stock_code} 价格预测 ({len(predictions)}天)",
            xaxis_title="日期",
            yaxis_title="价格 (¥)",
            height=500,
            showlegend=True
        )
        
        st.plotly_chart(fig, use_container_width=True)
    
    def _display_risk_assessment(self, risk_data):
        """显示风险评估"""
        if not risk_data:
            return
        
        st.subheader("⚠️ 风险评估")
        
        col1, col2 = st.columns(2)
        
        with col1:
            st.metric("历史波动率", f"{risk_data.get('volatility', 0):.2f}%")
            st.metric("最大回撤", f"{risk_data.get('max_drawdown', 0):.2f}%")
        
        with col2:
            st.info(f"🎯 风险等级: {risk_data.get('risk_level', '未知')}")
            st.info(f"💡 投资建议: {risk_data.get('recommendation', '谨慎投资')}")
    
    def _display_model_comparison(self, individual_predictions):
        """显示各模型预测对比"""
        if not individual_predictions:
            return
        
        st.subheader("🤖 预测模型对比")
        
        model_data = []
        for model_name, pred_data in individual_predictions.items():
            if isinstance(pred_data, dict) and 'predictions' in pred_data:
                predictions = pred_data['predictions']
                if predictions:
                    trend = pred_data.get('trend', '未知')
                    final_price = predictions[-1] if isinstance(predictions, list) else 0
                    model_data.append({
                        '模型': model_name,
                        '预测趋势': trend,
                        '预期价格': f"¥{final_price:.2f}" if final_price > 0 else "N/A"
                    })
        
        if model_data:
            model_df = pd.DataFrame(model_data)
            st.dataframe(model_df, use_container_width=True)
    
    def _render_investment_advice(self):
        """渲染投资建议页面"""
        st.header("📋 投资建议总结")
        
        if 'selected_stocks' not in st.session_state:
            st.info("⏳ 请先选择股票并完成分析")
            return
        
        selected_stocks = st.session_state['selected_stocks']
        
        st.subheader("🎯 投资组合建议")
        
        for stock_code in selected_stocks:
            if f'prediction_{stock_code}' in st.session_state:
                self._display_stock_summary(stock_code)
        
        # 整体投资建议
        self._display_portfolio_advice(selected_stocks)
    
    def _display_stock_summary(self, stock_code):
        """显示单只股票总结"""
        prediction_data = st.session_state[f'prediction_{stock_code}']
        result = prediction_data['result']
        
        with st.expander(f"📊 {stock_code} - {self._get_stock_name(stock_code)}", expanded=True):
            col1, col2, col3 = st.columns(3)
            
            with col1:
                st.metric("预测趋势", result.get('trend', '未知'))
                st.metric("价格变化", f"{result.get('price_change_pct', 0):+.2f}%")
            
            with col2:
                st.metric("置信度", f"{result.get('confidence', 0):.1%}")
                risk_level = result.get('risk_assessment', {}).get('risk_level', '未知')
                st.metric("风险等级", risk_level)
            
            with col3:
                current_price = result.get('current_price', 0)
                st.metric("当前价格", f"¥{current_price:.2f}")
                
                # 投资建议
                recommendation = result.get('risk_assessment', {}).get('recommendation', '观望')
                st.info(f"💡 {recommendation}")
    
    def _display_portfolio_advice(self, selected_stocks):
        """显示投资组合建议"""
        st.subheader("💼 投资组合配置建议")
        
        # 收集所有预测数据
        portfolio_data = []
        total_confidence = 0
        
        for stock_code in selected_stocks:
            if f'prediction_{stock_code}' in st.session_state:
                result = st.session_state[f'prediction_{stock_code}']['result']
                
                confidence = result.get('confidence', 0)
                price_change = result.get('price_change_pct', 0)
                risk_level = result.get('risk_assessment', {}).get('risk_level', '中等风险')
                
                portfolio_data.append({
                    'stock_code': stock_code,
                    'confidence': confidence,
                    'expected_return': price_change,
                    'risk_level': risk_level
                })
                
                total_confidence += confidence
        
        if not portfolio_data:
            st.warning("没有足够的分析数据生成投资建议")
            return
        
        # 计算权重分配
        st.write("### 📊 建议仓位配置")
        
        for data in portfolio_data:
            # 基于置信度和收益预期计算权重
            weight = (data['confidence'] * (1 + abs(data['expected_return']) / 100)) / len(portfolio_data)
            weight = min(weight * 100, 40)  # 单只股票最多40%
            
            col1, col2 = st.columns([3, 1])
            with col1:
                st.write(f"**{data['stock_code']}** - {self._get_stock_name(data['stock_code'])}")
                st.progress(weight / 40)  # 相对于最大权重的进度条
            
            with col2:
                st.write(f"{weight:.1f}%")
                st.write(f"风险: {data['risk_level']}")
        
        # 整体建议
        st.write("### 💡 总体投资建议")
        
        avg_confidence = total_confidence / len(portfolio_data)
        avg_return = sum(d['expected_return'] for d in portfolio_data) / len(portfolio_data)
        
        if avg_confidence > 0.6 and avg_return > 5:
            st.success("🚀 投资组合具有较好的增长潜力，建议积极配置")
        elif avg_confidence > 0.4 and avg_return > 0:
            st.info("📈 投资组合表现平稳，建议适度配置")
        else:
            st.warning("⚠️ 市场不确定性较高，建议谨慎投资或降低仓位")
        
        # 风险提示
        st.write("### ⚠️ 风险提示")
        st.warning("""
        **重要声明:**
        - 本系统提供的分析和预测仅供参考，不构成投资建议
        - 股票投资存在风险，可能面临本金损失
        - 请根据自身风险承受能力进行投资决策
        - 建议分散投资，控制单只股票仓位
        - 定期关注市场变化，及时调整投资策略
        """)
    
    def _get_stock_name(self, stock_code):
        """获取股票名称"""
        try:
            if 'filtered_stocks' in st.session_state:
                filtered_stocks = st.session_state['filtered_stocks']
                name_row = filtered_stocks[filtered_stocks['code'] == stock_code]
                if not name_row.empty:
                    return name_row['name'].iloc[0]
            return "未知"
        except:
            return "未知"

def main():
    """主函数"""
    app = StockAnalysisApp()
    app.run()

if __name__ == "__main__":
    main()
